/** Clase para realizar consultas tipo GET y GETNEXT **/

package common;

import java.io.IOException;
import java.util.LinkedList;

import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.event.*;
import org.snmp4j.smi.*;


public class Consulta {

    private Snmp snmp; //objeto para la comunicacion SNMP

    private String type; //tipo de consulta

    private SesionSNMP sesion; //sesion SNMP

    private OID[] ultimosOIDs; //ultimos OIDs recibidos al hacer GETNEXT

    /* Constructor */
    public Consulta(SesionSNMP sesion){
        this.sesion = sesion;
        snmp = sesion.getSnmp();
    }

    /* Realizar una consulta tipo GET */
    public Variable [] get(OID[] oids) throws IOException {
        type = "get";

        // Enviar la peticion
	ResponseEvent event = getEvent(oids);

        // Recoger las respuestas
        Variable []respuestas = new Variable[oids.length];
        for (int i = 0; i<oids.length; i++) {
            respuestas[i] = event.getResponse().get(i).getVariable();
 	}
	return respuestas;
        
    } //get

    /* Realizar una consulta tipo GETNEXT */
    public Variable[] getNext(OID [] oids) throws IOException{
        type = "getnext";

        // Enviar la peticion
	ResponseEvent event = getEvent(oids);
        
        // Recoger las respuestas
        Variable []respuestas = new Variable[oids.length];
        ultimosOIDs = new OID[oids.length];
        for (int i = 0; i<oids.length; i++) {
            respuestas[i] = event.getResponse().get(i).getVariable();
            ultimosOIDs[i] = event.getResponse().get(i).getOid();
 	}
	return respuestas;

    } //getNext

    /* Almacenar en una lista todos los valores que tiene una columna
    en una tabla */
    public LinkedList getColumn(OID oid){

        LinkedList  values = new LinkedList();

        try{
            Variable []respuestas = getNext(new OID[]{oid});

            int num = oid.size(); // caracteres numericos en el OID

            // Comprobar si el OID obtenido es hijo del nodo en cuestion para
            // constatar si se sigue en la misma columna
            while(ultimosOIDs[0].leftMostCompare(num, oid) == 0){
                values.add(respuestas[0]);
                respuestas = getNext(new OID[]{ultimosOIDs[0]});
            }

        }catch(java.io.IOException ioex){
            System.err.println("Error mientras se hacia la consulta.");
            return null;
        }

        return values;

    } //getColum

    /* Enviar la peticion */
    private ResponseEvent getEvent(OID oids[]) throws IOException {

        // Crear la PDU con los OIDs
	PDU pdu = new PDU();
 	for (OID oid_index : oids) {
 	     pdu.add(new VariableBinding(oid_index));
 	}
        if (type.equalsIgnoreCase("get")) //diferenciar los 2 tipos de consultas
            pdu.setType(PDU.GET);
        else pdu.setType(PDU.GETNEXT);

        // Enviar la consulta
 	ResponseEvent event = snmp.send(pdu, sesion.getTarget(), null);
	if(event != null) {
             return event;
	}
	throw new RuntimeException("Query timed out");

    } //getEvent

    /* Ultimos OIDs por los que se ha consultado */
    public OID[] getUltimosOIDs(){
        return ultimosOIDs;
    }

} //class
